package com.sikaryofficial.backend.service.store;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.sikaryofficial.backend.constant.RedisCacheKey;
import com.sikaryofficial.backend.domain.entity.BrandTasteEvaluateViews;
import com.sikaryofficial.backend.domain.entity.StoreView;
import com.sikaryofficial.backend.domain.entity.StoreViewDetail;
import com.sikaryofficial.backend.mapper.StoreViewDetailMapper;
import com.sikaryofficial.backend.mapper.StoreViewMapper;
import com.sikaryofficial.backend.service.evaluate.EvaluateViewEvent;
import com.sikaryofficial.common.core.constant.BrandEnum;
import com.sikaryofficial.common.core.constant.CacheBusinessConstants;
import com.sikaryofficial.common.redis.service.RedisService;
import com.sikaryofficial.common.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author : qinjinyuan
 * @desc : 店铺监听处理
 * @date : 2023/11/01 17:29
 */
@Component
@Slf4j
public class StoreListener {
    private static final Long SECURITY_DEFAULT_USER_ID = 0L;
    @Autowired
    private StoreCacheService storeCacheService;
    @Autowired
    private RedisService redisService;

    @Autowired
    private StoreViewMapper storeViewMapper;
    @Autowired
    private StoreViewDetailMapper storeViewDetailMapper;


    /**
     * TransactionalEventListener 当调用监听前的 事务提交后，进行缓存数据更新
     *
     * @param event
     */
    @TransactionalEventListener(
            phase = TransactionPhase.AFTER_COMMIT, classes = StoreCacheEvent.class)
    public void processStoreCacheEvent(StoreCacheEvent event) {
        // 对最新的店铺缓存进行清理
        Collection<String> keys = redisService.keys(RedisCacheKey.HISMK_STORE_EVALUATE_LIST_PREFIX + "*");
        for (String key : keys) {
            redisService.deleteObject(key);
        }
        storeCacheService.updateStoreCache(event.getStoreListDTO());
    }

    /**
     * 监听 详情查看功能： 增加店铺查阅量数据
     *
     * @param event
     */
    @EventListener
    @Async("asyncTaskExecutor")
    public void processViewsEvent(StoreViewEvent event) {
        Long userId = SecurityUtils.getUserId();
        if (Objects.isNull(userId) || SECURITY_DEFAULT_USER_ID.equals(userId)) {
            // 未登录用户，不统计阅读量
            log.info("用户未登录（userId: {}），不记录店铺阅读量", userId);
            return;
        }
        String cacheKey = buildKey(event.getStoreId(), userId);
        if (Boolean.TRUE.equals(redisService.hasKey(cacheKey))) {
            // key存在，则不进行统计
            return;
        }
        processViewData(event, userId);
        // 缓存2分钟
        redisService.setCacheObject(cacheKey, true, 2L, TimeUnit.MINUTES);
    }

    private void processViewData(StoreViewEvent event, Long userId) {
        // 新增店铺查阅量统计
        StoreView entity = StoreView.builder()
                .storeId(event.getStoreId())
                .createdBy(userId)
                .viewCount(1L)
                .storeViewId(IdWorker.getId())
                .build();
        storeViewMapper.insertViews(entity);
        // 新增查阅量明细
        StoreViewDetail detail = StoreViewDetail.builder()
                .storeId(event.getStoreId())
                .createdBy(userId)
                .storeViewDetailId(IdWorker.getId())
                .build();
        storeViewDetailMapper.insert(detail);
    }

    private String buildKey(Long storeId, Long userId) {
        return MessageFormat.format(RedisCacheKey.STORE_VIEW_COUNT_CACHE, storeId.toString(), userId.toString());
    }
}
